package com.example.james.fragmenttest;

import android.content.Intent;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.RelativeLayout;
import android.widget.Toast;

import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.Scheduler;
import io.reactivex.Single;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
import io.reactivex.subjects.AsyncSubject;
import io.reactivex.subjects.BehaviorSubject;
import io.reactivex.subjects.PublishSubject;
import io.reactivex.subjects.ReplaySubject;
import io.reactivex.subjects.Subject;

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        if (null != savedInstanceState){
            String data = savedInstanceState.getString("data");
            Toast.makeText(this, data, Toast.LENGTH_LONG).show();
        }

        Intent intent = getIntent();

        if (intent != null){
            Toast.makeText(this, "intent is not null", Toast.LENGTH_LONG).show();
        }

        Button button = findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                replaceFragment(new AnotherRightFragment());
            }
        });
        replaceFragment(new RightFragment());


        Button button2 = findViewById(R.id.button2);
        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                subjectDemo();
//                behaviorSubjectDemo();
//                publishSubjectDemo();
//                replaySubjectDemo();
            }
        });

        Button button3 = findViewById(R.id.button3);
        button3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                behaviorSubjectDemo();
            }
        });

        Button button4 = findViewById(R.id.button4);
        button4.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                publishSubjectDemo();
            }
        });

        Button button5 = findViewById(R.id.button5);
        button5.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                replaySubjectDemo();
            }
        });

        Button button6 = findViewById(R.id.button6);
        button6.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                doOnNextDemo();
            }
        });

        Button button7 = findViewById(R.id.button7);
        button7.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                doOnSubscribeDemo();
            }
        });

        Button button8 = findViewById(R.id.button8);
        button8.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                caseDemo();
            }
        });
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        String msg = "this is data";
        outState.putString("data", msg);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()){
            case R.id.add_item:
                Toast.makeText(MainActivity.this, "You click Add", Toast.LENGTH_LONG).show();
                break;
            case R.id.remove_item:
                Toast.makeText(this, "You click Remove", Toast.LENGTH_LONG).show();
                break;
            default:
                break;
        }
        return true;
    }

    private void caseDemo() {
        Integer r = test(1);
        Log.e(TAG, r.toString());
    }

    private int test(Integer i){
        switch (i){
            case 1:
                Log.e(TAG, "case 1");
                return 1;
            case 2:
                Log.e(TAG, "case 2");
                return 2;
            default:
                Log.e(TAG, "case 0");
                return 0;
        }
    }

    private void doOnSubscribeDemo() {
        Log.i(TAG, "doOnSubscribeDemo thread id: " + Thread.currentThread().getId());

        Observable<Integer> observable = Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> e) throws Exception {
                Log.i(TAG, "subscribe thread id: " + Thread.currentThread().getId());
                e.onNext(1);
                e.onComplete();
            }
        });


        observable
                .subscribeOn(Schedulers.io())
//                .observeOn(AndroidSchedulers.mainThread())
                .doOnSubscribe(new Consumer<Disposable>() {
                    @Override
                    public void accept(Disposable disposable) throws Exception {
                        Log.i(TAG, "doOnSubscribe accept thread id:" + Thread.currentThread().getId());
                    }
                })
                .map(new Function<Integer, Integer>() {
                    @Override
                    public Integer apply(Integer integer) throws Exception {
                        Log.i(TAG, "map thread id:" + Thread.currentThread().getId());
                        return integer * 10;
                    }
                })
                .observeOn(AndroidSchedulers.mainThread())
                .doOnNext(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer integer) throws Exception {
                        integer = integer + 1;
                        Log.i(TAG, "doOnNext accept thread id:" + Thread.currentThread().getId());
                    }
                })
//                .subscribeOn(AndroidSchedulers.mainThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer integer) throws Exception {
                        Log.i(TAG, integer.toString());
                        Log.i(TAG, "accept thread id:" + Thread.currentThread().getId());
                    }
                });
    }

    private void doOnNextDemo() {
        Log.i(TAG, "doOnNextDemo thread id:" + Thread.currentThread().getId());
        Observable<Integer> observable = Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> e) throws Exception {
                Log.i(TAG, "subscribe thread id:" + Thread.currentThread().getId());
                Thread.sleep(2000);
                e.onNext(1);
                e.onComplete();
            }
        });

        observable
                .subscribeOn(Schedulers.io())
//                .subscribeOn(AndroidSchedulers.mainThread())
                .observeOn(AndroidSchedulers.mainThread())
                .doOnNext(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer o) throws Exception {
                        Log.i(TAG, o.toString());
                        Log.i(TAG, "doOnNest thread id:" + Thread.currentThread().getId());
                    }
                })
//                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer o) throws Exception {
                        Log.i(TAG, o.toString());
                        Log.i(TAG, "accept thread id:" + Thread.currentThread().getId());
                    }
                });

    }

    private void subjectDemo() {
        AsyncSubject as = AsyncSubject.create();
        as.onNext(1);
        as.onNext(2);
        as.onNext(3);
        as.onComplete();
        as.subscribe(
                new Consumer<Integer>() {
                    @Override
                    public void accept(Integer o) throws Exception {
                        Log.i(TAG, String.valueOf(o));
                    }
                });
    }

    private void behaviorSubjectDemo(){
        BehaviorSubject behaviorSubject = BehaviorSubject.createDefault(-1);
        behaviorSubject.onNext(1);
        behaviorSubject.onNext(2);
        behaviorSubject.subscribe(new Consumer<Integer>() {
            @Override
            public void accept(Integer o) throws Exception {
                Log.i(TAG, o.toString());
            }
        });
        behaviorSubject.onNext(3);

        Observable observable = Observable.create(new ObservableOnSubscribe() {
            @Override
            public void subscribe(ObservableEmitter e) throws Exception {
                e.onNext(123);
                e.onComplete();
            }
        });
    }

    private void publishSubjectDemo(){
        PublishSubject publishSubject = PublishSubject.create();
        publishSubject.onNext(1);
        publishSubject.subscribe(new Consumer<Integer>() {
            public void accept(Integer o) throws Exception {
                Log.i(TAG, o.toString());
            }
        });
                publishSubject.onNext(3);
    }

    private void replaySubjectDemo(){
        ReplaySubject replaySubject = ReplaySubject.create();
        replaySubject.onNext(1);
        replaySubject.onNext(2);
        replaySubject.onComplete();
        Log.i(TAG, "current thread:" + Thread.currentThread().getId());
        replaySubject.subscribe(new Consumer<Integer>() {
            @Override
            public void accept(Integer integer) throws Exception {
                Log.i(TAG, "current working thread:" + Thread.currentThread().getId());
                Log.i(TAG, integer.toString());
            }
        });
    }

    private void replaceFragment(Fragment fragment){
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction.replace(R.id.right_layout, fragment);
        fragmentTransaction.addToBackStack(null);
        fragmentTransaction.commit();
    }

    private void serializedSubjectDemo(){
    }
}
